/**
 * 文件名：****.java
 * 版权：Copyright Lightkit All Rights Reserved.
 * 描述：*****
 */
package com.lightkits.wms.domain.allot.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.lightkits.common.MessageUtil;
import com.lightkits.common.TransactionValidate;
import com.lightkits.common.db.entity.BdTag;
import com.lightkits.common.db.entity.FndOrganizationBase;
import com.lightkits.common.db.entity.FndWarehouse;
import com.lightkits.common.db.entity.WmRequestLine;
import com.lightkits.common.db.entity.category.FndCategoryBase;
import com.lightkits.common.db.entity.category.FndCategoryTl;
import com.lightkits.framework.common.exception.LightKitsBizException;
import com.lightkits.framework.common.logging.Logger;
import com.lightkits.framework.common.logging.LoggerFactory;
import com.lightkits.framework.common.model.CheckResult;
import com.lightkits.framework.common.model.IResult;
import com.lightkits.framework.common.utility.object.ObjectUtil;
import com.lightkits.framework.common.utility.object.ParseUtil;
import com.lightkits.framework.common.utility.validate.IntegrityValidator;
import com.lightkits.framework.soa.common.pipeline.session.SessionInfo;
import com.lightkits.wms.database.dao.WmsBdTagMapper;
import com.lightkits.wms.database.dao.WmsWarehouseMapper;
import com.lightkits.wms.database.model.BdTagMesModel;
import com.lightkits.wms.database.model.KVCodeModel;
import com.lightkits.wms.domain.allot.GetTagMessService;
import com.lightkits.wms.dto.allot.model.TagMessageDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * GetTagMessServiceImpl
 *
 * @author jing.wei@hand-china.com
 * Created on 2019/5/21 0:22
 */
@Service
public class GetTagMessServiceImpl implements GetTagMessService {
    private static final Logger LOGGER =
            LoggerFactory.getLogger(GetTagMessServiceImpl.class);

    private final WmsBdTagMapper wmsBdTagMapper;
    private final WmsWarehouseMapper wmsWarehouseMapper;

    @Autowired
    public GetTagMessServiceImpl(WmsBdTagMapper wmsBdTagMapper,
                                 WmsWarehouseMapper wmsWarehouseMapper) {
        this.wmsBdTagMapper = wmsBdTagMapper;
        this.wmsWarehouseMapper = wmsWarehouseMapper;
    }

    /**
     * 获取调拨发出条码信息
     *
     * @param tagCode 条码编码
     * @return 条码参数
     **/
    @Override
    public CheckResult<TagMessageDto> getTagMes(String tagCode, boolean viaFlag,
                                                boolean bookFlag, String organizationId) {
        CheckResult<TagMessageDto> checkResult = new CheckResult<>();
        checkResult.setSuccessful(true);
        TagMessageDto dto = new TagMessageDto();
        try {
            IResult iResult = checkParams(tagCode, organizationId);
            if (!iResult.isSuccessful()) {
                return iResult.fill(checkResult);
            }
            List<BdTagMesModel> mesModel = wmsBdTagMapper.getTagMesByParams(tagCode,
                    ParseUtil.tryLongWithException(organizationId),
                    SessionInfo.languageCode());
            if (ObjectUtil.isNullOrEmpty(mesModel)|| mesModel.size() > 1) {
                checkResult.setSuccessful(false);
                checkResult.setMessage(MessageUtil.getSysMessage("TAG_NOT_EXSIT_OR_CANNOT_UESD"));
                return checkResult;

            }
            dto = convertDTO(mesModel.get(0), viaFlag, bookFlag);
            if (viaFlag && dto.getViaWarehouseId().equals(dto.getFromWarehouseId())) {
                checkResult.setSuccessful(false);
                checkResult.setMessage(MessageUtil.getSysMessage("TAG_NOT_EXSIT_OR_CANNOT_UESD"));
                return checkResult;
            }
            if (bookFlag && dto.getBookWarehouseId().equals(dto.getFromWarehouseId())) {
                checkResult.setSuccessful(false);
                checkResult.setMessage(MessageUtil.getSysMessage("TAG_NOT_EXSIT_OR_CANNOT_UESD"));
                return checkResult;
            }
            checkResult.setData(dto);

        } catch (Exception e) {
            LOGGER.error("Get Tag Failed", e);
            throw new LightKitsBizException(e);
        }
        return checkResult;
    }

    /**
     * 获取调拨接收条码信息
     *
     * @param tagCode 条码编码
     * @param orgId   当前组织ID
     * @return 条码参数
     **/
    @Override
    public CheckResult<TagMessageDto> getComTagMes(String tagCode, String orgId, boolean viaFlag, boolean bookFlag) {
        CheckResult<TagMessageDto> checkResult = new CheckResult<>();
        checkResult.setSuccessful(true);
        TagMessageDto dto = new TagMessageDto();
        try {
            IResult iResult = checkComParams(tagCode, orgId);
            if (!iResult.isSuccessful()) {
                return iResult.fill(checkResult);
            }
            List<BdTagMesModel> mesModel = wmsBdTagMapper.getComTagMesByParams(
                    tagCode, orgId, SessionInfo.languageCode());
            if (mesModel == null || mesModel.size() > 1 || mesModel.size() == 0) {
                checkResult.setSuccessful(false);
                checkResult.setMessage(
                        MessageUtil.getSysMessage("TAG_NOT_EXSIT_OR_CANNOT_UESD"));
                return checkResult;

            }
            dto = convertDTO(mesModel.get(0), viaFlag, bookFlag);
            if (viaFlag && dto.getViaWarehouseId().equals(dto.getFromWarehouseId())) {
                checkResult.setSuccessful(false);
                checkResult.setMessage(MessageUtil.getSysMessage("TAG_NOT_EXSIT_OR_CANNOT_UESD"));
                return checkResult;
            }
            if (bookFlag && dto.getBookWarehouseId().equals(dto.getFromWarehouseId())) {
                checkResult.setSuccessful(false);
                checkResult.setMessage(MessageUtil.getSysMessage("TAG_NOT_EXSIT_OR_CANNOT_UESD"));
                return checkResult;
            }
            checkResult.setData(dto);

        } catch (Exception e) {
            LOGGER.error(MessageUtil.getSysMessage("TAG_NOT_EXSIT_OR_CANNOT_UESD"), e);
            throw new LightKitsBizException(e);
        }
        return checkResult;
    }

    /**
     * 校验调拨接收的参数
     *
     * @param tagCode 条码编码
     * @param orgId   组织Id
     * @return IResult
     **/
    private IResult checkComParams(String tagCode, String orgId) {
        try {
            IntegrityValidator.begin()
                    .validate(tagCode, "Tag Code");
            TransactionValidate check1 = TransactionValidate
                    .beginValidity(BdTag.class);
            check1.checkIdValidity(ObjectUtil.toString(tagCode), "TAG_CODE");

            check1 = TransactionValidate
                    .beginValidity(FndOrganizationBase.class);
            check1.checkIdValidity(ObjectUtil.toString(orgId), "ORGANIZATION_ID");
            //条码的有效性校验
            List<BdTag> bdTag = new BdTag()
                    .selectList(new <BdTag>EntityWrapper()
                            .eq(BdTag.TAG_CODE, tagCode));
            if (ObjectUtil.isNullOrEmpty(bdTag) || bdTag.size() != 1) {
                return IResult.fail(MessageUtil.getSysMessage("CODE_NOT_EXIST_OR_UNENABLED"));
            }
            FndWarehouse fndWarehouse = new FndWarehouse()
                    .selectById(bdTag.get(0).getWarehouseId());
            if (fndWarehouse == null) {
                return IResult.fail("该仓库参数无效");
            }
            //扫描条码之前必须在中转仓
            FndCategoryBase categoryBase = new FndCategoryBase().selectOne(new EntityWrapper()
                    .eq(FndCategoryBase.ORGANIZATION_ID, bdTag.get(0).getOwnerOrganizationId())
                    .eq(FndCategoryBase.CATEGORY_CODE, "VIA"));
            List<FndWarehouse> warehouse = new FndWarehouse()
                    .selectList(new EntityWrapper()
                            .eq(FndWarehouse.ORGANIZATION_ID, bdTag.get(0).getOwnerOrganizationId())
                            .eq(FndWarehouse.ENABLED_FLAG, true)
                            .eq(FndWarehouse.WAREHOUSE_CATEGORY_ID, categoryBase.getId()));
            if (ObjectUtil.isNullOrEmpty(warehouse) || warehouse.size() > 1) {
                throw new LightKitsBizException("条码接收前必须属于中转仓");
            }
            //条码对应领料单的状态校验
            WmRequestLine line = new WmRequestLine().selectById(bdTag.get(0).getDocumentId());
            if (!line.getLineStatus().equals("RELEASED")) {
                throw new LightKitsBizException(
                        MessageUtil.getSysMessage("CODE_STATUS_NOT_NEW_OR_PRINTED"));
            }


        } catch (Exception e) {
            LOGGER.error("参数校验错误", e);
            throw new LightKitsBizException(e);
        }
        return IResult.success();
    }

    /**
     * 调拨发出参数校验
     *
     * @param tagCode        条码编码
     * @param organizationId 组织Id
     * @return IResult
     **/
    private IResult checkParams(String tagCode, String organizationId) {
        try {

            IntegrityValidator.begin()
                    .validate(organizationId, "Organization Id")
                    .validate(tagCode, "Tag Code");
            TransactionValidate check1 = TransactionValidate
                    .beginValidity(BdTag.class);
            check1.checkIdValidity(ObjectUtil.toString(tagCode), "TAG_CODE");

            check1 = TransactionValidate
                    .beginValidity(FndOrganizationBase.class);
            check1.checkIdValidity(ObjectUtil.toString(organizationId), "ORGANIZATION_ID");
            //条码的有效性校验
            List<BdTag> bdTag = new BdTag()
                    .selectList(new <BdTag>EntityWrapper()
                            .eq(BdTag.TAG_CODE, tagCode));
            if (ObjectUtil.isNullOrEmpty(bdTag) || bdTag.size() != 1) {
                return IResult.fail(MessageUtil.getSysMessage("TAG_NOT_EXSIT_OR_CANNOT_UESD"));
            }
            //条码的调拨
            FndWarehouse fndWarehouse = new FndWarehouse()
                    .selectById(bdTag.get(0).getWarehouseId());
            if (fndWarehouse == null) {
                return IResult.fail("The warehouseId is inValid");
            }
            FndCategoryTl fndCategoryTl = new FndCategoryTl()
                    .selectOne(new EntityWrapper()
                            .eq(FndCategoryTl.CATEGORY_ID,
                                    fndWarehouse.getWarehouseCategoryId()));

            List<KVCodeModel> models = wmsWarehouseMapper
                    .querySysCode("FND_ ALLOT_WAREHOUSE",
                            "",
                            fndCategoryTl.getSegment1());
            if (ObjectUtil.isNullOrEmpty(models) || models.size() != 1) {
                return IResult.fail(MessageUtil
                        .getSysMessage("CODE_WAREHOUSE_ILLEGAL"));
            }
        } catch (LightKitsBizException e) {
            return e.result();
        }
        return IResult.success();
    }

    /**
     * 转换实体
     *
     * @param mesModel model
     * @param viaFlag  是否校验中转仓
     * @param bookFlag 是否校验定金仓
     * @return TagMessageDto
     */
    private TagMessageDto convertDTO(BdTagMesModel mesModel, boolean viaFlag, boolean bookFlag) {
        TagMessageDto dto = new TagMessageDto();
        dto.setBrand(mesModel.getBrand());
        dto.setTagId(mesModel.getTagId());
        dto.setInternalSettlementPrice(mesModel.getInternalSettlementPrice());
        dto.setTagCode(mesModel.getTagCode());
        dto.setRemark(mesModel.getRemark());
        dto.setToOrgId(mesModel.getToOrgId());
        dto.setToOrgName(mesModel.getToOrgName());
        //获取同组织下的中转仓
        if (viaFlag) {
            if (ObjectUtil.isNullOrEmpty(mesModel.getViaWarehouseId())) {
                FndCategoryBase categoryBase = new FndCategoryBase().selectOne(new EntityWrapper()
                        .eq(FndCategoryBase.ORGANIZATION_ID, mesModel.getFromOrgId())
                        .eq(FndCategoryBase.CATEGORY_CODE, "VIA"));
                List<FndWarehouse> warehouse = new FndWarehouse()
                        .selectList(new EntityWrapper()
                                .eq(FndWarehouse.ORGANIZATION_ID, mesModel.getFromOrgId())
                                .eq(FndWarehouse.ENABLED_FLAG, true)
                                .eq(FndWarehouse.WAREHOUSE_CATEGORY_ID, categoryBase.getId()));
                if (ObjectUtil.isNullOrEmpty(warehouse) || warehouse.size() > 1) {
                    throw new LightKitsBizException("the Via Warehouse is null");
                }
                dto.setViaWarehouseId(warehouse.get(0).getId().toString());
            } else {
                dto.setViaWarehouseId(mesModel.getViaWarehouseId());
            }
        }

        //获取同组织下的定金仓
        if (bookFlag) {
            FndCategoryBase categoryBase = new FndCategoryBase().selectOne(new EntityWrapper()
                    .eq(FndCategoryBase.ORGANIZATION_ID, mesModel.getFromOrgId())
                    .eq(FndCategoryBase.CATEGORY_CODE, "BOOKED"));
            List<FndWarehouse> warehouse = new FndWarehouse()
                    .selectList(new EntityWrapper()
                            .eq(FndWarehouse.ORGANIZATION_ID, mesModel.getFromOrgId())
                            .eq(FndWarehouse.ENABLED_FLAG, true)
                            .eq(FndWarehouse.WAREHOUSE_CATEGORY_ID, categoryBase.getId()));
            if (ObjectUtil.isNullOrEmpty(warehouse) || warehouse.size() > 1) {
                throw new LightKitsBizException("the Booked Warehouse is null");
            }
            dto.setBookWarehouseId(warehouse.get(0).getId().toString());
        }
        dto.setToWarehouseId(mesModel.getToWarehouseId());
        dto.setToWarehouseName(mesModel.getToWarehouseName());
        dto.setFromOrgId(mesModel.getFromOrgId());
        dto.setFromOrgName(mesModel.getFromOrgName());
        dto.setFromWarehouseId(mesModel.getFromWarehouseId());
        dto.setFromWarehouseName(mesModel.getFromWarehouseName());
        dto.setHeaderId(mesModel.getReqeustHeaderId());
        dto.setLinesId(mesModel.getRequestLineId());
        dto.setItemId(mesModel.getItemId());
        dto.setItemCode(mesModel.getItemCode());
        dto.setItemDesc(mesModel.getItemDesc());
        dto.setUomCode(mesModel.getUomCode());
        dto.setQuantity(mesModel.getQuantity());
        int ram = (int) (Math.random() * 1000);
        dto.setSalePrice(String.valueOf(ram));
        return dto;
    }
}
